﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml.Linq;

using ICSharpCode.AvalonEdit;
using ICSharpCode.AvalonEdit.Folding;
using ICSharpCode.AvalonEdit.Indentation;
using ICSharpCode.AvalonEdit.Highlighting;

namespace VisualRibbonEditor
{
	public partial class WebResourceDialog : UserControl, IDialog
	{

		private SynchronizedCollection<KeyValuePair<string, WebResourceType>> webResources = new SynchronizedCollection<KeyValuePair<string, WebResourceType>>();
		public ResourceType ResourceType { get; internal set; }
		private string selectedWebResource = "";

		public WebResourceDialog(ResourceType type = ResourceType.All, string selectedWebResource = "")
		{
			InitializeComponent();
			if (type == ResourceType.Image) SetUIElementsSize(WebResourceType.PNGformat);
			if (type == ResourceType.All) OKButton.Visibility = Visibility.Collapsed;
			WordWrap.IsChecked = true; // Enable word-wrap by default
			this.ResourceType = type;

			WebResourceManager.GetAllWebResourcesAsync((webResources) =>
			{
				this.webResources = webResources;
				this.selectedWebResource = selectedWebResource;
				PublishResourceList();
				WebResources.Focus();
				if (WebResources.SelectedItem != null) ((ListBoxItem)WebResources.SelectedItem).Focus();
			});
		}

		private void PublishResourceList(string quickSearch = "")
		{
			this.Loading.Visibility = Visibility.Visible;
			int index = 0;
			ListBoxItem listItem;
			WebResources.Items.Clear();
			foreach (KeyValuePair<string, WebResourceType> wr in webResources)
			{
				switch (this.ResourceType)
				{
					case ResourceType.MarkupDocument:
						if (wr.Value != WebResourceType.Data_XML && wr.Value != WebResourceType.Webpage_HTML && wr.Value != WebResourceType.StyleSheet_XSL) continue;
						break;
					case ResourceType.CSS:
						if (wr.Value != WebResourceType.StyleSheet_CSS) continue;
						break;
					case ResourceType.Script:
						if (wr.Value != WebResourceType.Script_JScript) continue;
						break;
					case ResourceType.Image:
						if (wr.Value != WebResourceType.GIFformat && wr.Value != WebResourceType.ICOformat && wr.Value != WebResourceType.JPGformat && wr.Value != WebResourceType.PNGformat) continue;
						break;
					case ResourceType.Silverlight:
						if (wr.Value != WebResourceType.Silverlight_XAP) continue;
						break;
					case ResourceType.All:
					default:
						break;
				}
				// Filter
				quickSearch = quickSearch.ToLowerInvariant();
				if (!String.IsNullOrWhiteSpace(quickSearch) && !wr.Key.ToLowerInvariant().Contains(quickSearch)) continue;

				// Create ListBoxItem
				listItem = new ListBoxItem();
				listItem.Content = wr.Key;
				listItem.Tag = wr.Value;
				index = WebResources.Items.Add(listItem);
				if (selectedWebResource.Equals(wr.Key, StringComparison.InvariantCultureIgnoreCase))
				{
					WebResources.SelectedIndex = index;
					WebResources.ScrollIntoView(WebResources.SelectedItem);
				}
			}
			
			this.Loading.Visibility = Visibility.Collapsed;
		}

		private void OKButton_Click(object sender, RoutedEventArgs e)
		{
			if (DialogClosed != null && WebResources.SelectedItem != null)
			{
				DialogClosed(((ListBoxItem)WebResources.SelectedItem).Content);
			} else {
				DialogClosed(null);
			}
		}

		private void CancelButton_Click(object sender, RoutedEventArgs e)
		{
			if (DialogClosed != null)
			{
				DialogClosed(null);
			}
		}

		public event CloseDialogHandler DialogClosed;

		private void WebResourceDialog_KeyUp(object sender, KeyEventArgs e)
		{
			switch (e.Key) //
			{
				// ENTER
				case Key.Enter:
					if (OKButton.Visibility == Visibility.Visible) OKButton_Click(sender, new RoutedEventArgs());
					break;
				// ESC
				case Key.Escape:
					if (DialogClosed != null) DialogClosed(null);
					break;
				default:
					break;
			}
		}

		private void WordWrap_OnChange(object sender, RoutedEventArgs e)
		{
			Preview_Editor.WordWrap = (WordWrap.IsChecked != null && WordWrap.IsChecked.Value == true);
		}

		private void ContextMenu_ContextMenuOpening(object sender, ContextMenuEventArgs e)
		{
			MenuItem_Copy.IsEnabled = !String.IsNullOrEmpty(Preview_Editor.SelectedText);
		}

		private void Preview_HideAll()
		{
			Preview_NotAvailable.Visibility = Visibility.Collapsed;
			Preview_Loading.Visibility = Visibility.Collapsed;
			Preview_Image.Visibility = Visibility.Collapsed;
			Preview_ImageSize.Visibility = Visibility.Collapsed;
			Preview_Editor.Visibility = Visibility.Collapsed;
			WordWrap.Visibility = Visibility.Collapsed;
		}

		public void SetUIElementsSize(WebResourceType type)
		{
			switch (type)
			{
				case WebResourceType.GIFformat:
				case WebResourceType.ICOformat:
				case WebResourceType.JPGformat:
				case WebResourceType.PNGformat:
					//MainRow.Height = new GridLength(280); // 280
					//PreviewColumn.Width = new GridLength(185); // 185
					LayoutRoot.Height = 280 + 40 + 40 + 30;
					LayoutRoot.Width = 300 + 185;
					Preview_Loading.Width = 50;
					Preview_Loading.Height = 5;
					GridSplitter.IsEnabled = false;
					break;
				default:
					break;
			}
		}

		private void PreviewLoading_Show()
		{
			Preview_Loading.IsIndeterminate = true;
			Preview_Loading.Visibility = Visibility.Visible;
		}

		private void PreviewLoading_Hide()
		{
			Preview_Loading.Visibility = Visibility.Collapsed;
			Preview_Loading.IsIndeterminate = false;
		}

		private void WebResources_SelectionChanged(object sender, RoutedEventArgs e)
		{
			if (WebResources.SelectedItem == null)
			{
				OKButton.IsEnabled = false;
				return;
			} else {
				OKButton.IsEnabled = true;
			}

			WebResourceType type = (WebResourceType)((ListBoxItem)WebResources.SelectedItem).Tag;
			string name = (String)((ListBoxItem)WebResources.SelectedItem).Content;

			Preview_HideAll();
			switch (type)
			{
				case WebResourceType.GIFformat:
				case WebResourceType.ICOformat:
				case WebResourceType.JPGformat:
				case WebResourceType.PNGformat:
					PreviewLoading_Show();
					WebResourceManager.GetWebResourceContent(name, bits =>
					{
						if (bits != null)
						{
							MemoryStream stream = new MemoryStream(bits);
							BitmapImage b = new BitmapImage();
							b.BeginInit();
							b.StreamSource = stream;
							b.EndInit();
							Preview_Image.SetValue(Image.SourceProperty, b);
							double w = b.PixelWidth;
							double h = b.PixelHeight;

							double MAX_WIDTH = 185 - 10; // 175
							double MAX_HEIGHT = 280 - 30; // 250

							double aspectRation = 1;

							if (w > MAX_WIDTH || h > MAX_HEIGHT)
							{
								// Resize image
								aspectRation = Math.Min(MAX_WIDTH / w, MAX_HEIGHT / h);
							}

							Preview_Image.Width = Math.Floor(w * aspectRation);
							Preview_Image.Height = Math.Floor(h * aspectRation);
							
							PreviewLoading_Hide();
							Preview_Image.Visibility = Visibility.Visible;
							Preview_ImageSize.Text = "Size: " + w + " x " + h;
							Preview_ImageSize.Visibility = Visibility.Visible;
						}
					});
					break;
				case WebResourceType.Data_XML:
				case WebResourceType.StyleSheet_XSL:
				case WebResourceType.Webpage_HTML:
				case WebResourceType.StyleSheet_CSS:
				case WebResourceType.Script_JScript:
					PreviewLoading_Show();
					WebResourceManager.GetWebResourceContent(name, bits =>
					{
						if (bits != null)
						{
							string text = Encoding.UTF8.GetString(bits);

							switch (type)
							{
								case WebResourceType.Data_XML:
								case WebResourceType.StyleSheet_XSL:
									Preview_Editor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("XML");
									/*
									XmlFoldingStrategy foldingStrategy = new XmlFoldingStrategy();
									Preview_Editor.TextArea.IndentationStrategy = new DefaultIndentationStrategy();
									FoldingManager foldingManager = FoldingManager.Install(Preview_Editor.TextArea);
									foldingStrategy.UpdateFoldings(foldingManager, Preview_Editor.Document);
									*/
									break;
								case WebResourceType.Webpage_HTML:
									Preview_Editor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("HTML");
									break;
								case WebResourceType.StyleSheet_CSS:
									Preview_Editor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("CSS");
									break;
								case WebResourceType.Script_JScript:
									Preview_Editor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("JavaScript");
									break;
							}
							Preview_Editor.Text = text;
							Preview_Editor.ScrollToHome();
							PreviewLoading_Hide();
							Preview_Editor.Visibility = Visibility.Visible;
							WordWrap.Visibility = Visibility.Visible;
						}
						else
						{
							Preview_HideAll();
							Preview_NotAvailable.Visibility = Visibility.Visible;
						}
					});
					break;
				default:
					Preview_HideAll();
					Preview_NotAvailable.Visibility = Visibility.Visible;
					break;
			}
		}

		private void QuickSearch_KeyUp(object sender, KeyEventArgs e)
		{
			TextBox c = (TextBox)sender;
			string text = String.Empty;
			if (!String.IsNullOrWhiteSpace(c.Text))
			{
				text = c.Text;
				QuickSearchLabel.Visibility = Visibility.Collapsed;
			}
			else
			{
				QuickSearchLabel.Visibility = Visibility.Visible;
			}

			PublishResourceList(text);
		}
	}
}